import os
import re
from urllib.parse import urljoin
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm

# 创建一个文件夹来存储图片
if not os.path.exists("Images"):
    os.mkdir("Images")


def get_image_urls(search_keyword, page):
    # 构建URL
    url = f"填写目标网页的URL"
    # url = f"https://www.vcg.com/creative-image/" + search_keyword
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
    }

    try:
        response = requests.get(url, headers=headers)
        response.encoding = "utf-8"
        html = response.text
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        html = None

    try:
        soup = BeautifulSoup(html, "html.parser")
    except Exception as e:
        print(f"无法解析HTML: {e}")
        soup = None
    # 根据实际获取分页数
    try:
        pagination_total = min(
            int(soup.find_all("span", class_="paginationTotal")[0].contents[2]),
            int(page),
        )
    except Exception as e:
        print(f"无法获取分页总数: {e}")
        pagination_total = 0

    # 遍历分页获取图片信息
    images = []
    for page in range(pagination_total):
        try:
            response = requests.get(f"{url}?page={page + 1}", headers=headers)
            response.encoding = "utf-8"
            html = response.text
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
            html = None

        try:
            soup = BeautifulSoup(html, "html.parser")
        except Exception as e:
            print(f"无法解析HTML: {e}")
            soup = None

        for img in soup.find_all("img", class_=True):
            image_url = urljoin("https://", img.get("data-src"))
            image_name = (
                re.sub('[\/:*?"<>|\n]', "_", img.get("alt"))
                .replace("图片购买", "")
                .replace("图片下载", "")
            )
            if image_url and image_name != "logo":
                images.append({"image_name": image_name, "image_url": image_url})
    return images


def download_images(images):
    if not os.path.exists("Images"):
        os.mkdir("Images")

    # 遍历图片标签并下载图片
    exists_index = {}
    with tqdm(total=len(images)) as pbar:
        for index, image in enumerate(images):
            try:
                # 检查URL是否可解析
                if not image.get("image_url"):
                    print(f"下载图片失败: 无效的URL")
                    continue

                image_data = requests.get(image["image_url"]).content
                # 检查图片是否为空
                if not image_data:
                    print(f"下载图片失败: 图片为空")
                    continue

                # 检查文件是否已存在
                image_name = image["image_name"]
                if os.path.exists(f"Images/{image_name}.jpg"):
                    if image_name in exists_index:
                        exists_index[image_name] += 1
                    else:
                        exists_index.update({image_name: 1})
                    with open(
                        f"Images/{image_name}_{exists_index[image_name]}.jpg",
                        "wb",
                    ) as f:
                        f.write(image_data)
                        print(f"重名文件：{image_name}下载完成")
                        pbar.update(1)
                else:
                    with open(f"Images/{image_name}.jpg", "wb") as f:
                        f.write(image_data)
                    pbar.set_description_str(f"{image_name}下载完成")
                    pbar.update(1)

            except requests.exceptions.RequestException as e:
                print(f"下载图片失败: {e}")
            except FileNotFoundError as e:
                print(f"无法创建文件夹: {e}")
            except IOError as e:
                print(f"文件写入失败: {e}")
            except PermissionError as e:
                print(f"无法写入文件夹: {e}")
            except Exception as e:
                print(f"下载图片失败: {e}")

        pbar.close()
        print(f"所有图片已下载完成！")


def input_validation(input_str, input_type, min_value=0):
    try:
        if input_type == "int":
            input_value = int(input_str)
            if input_value > min_value:
                return input_value
            else:
                raise ValueError(f"输入的值必须大于{min_value}")
        elif input_type == "str":
            return input_str
        else:
            raise ValueError(f"Invalid input type")
    except ValueError as e:
        print(f"输入错误：{e}")
        return None


if __name__ == "__main__":
    while True:
        search_keyword = input_validation(input(f"请输入搜索关键字："), "str")
        page = input_validation(input(f"请输入下载页数："), "int")

        if search_keyword and page:
            break
        else:
            print(f"输入不合法，请重新输入。")

    print(f"搜索中…")
    image_urls = get_image_urls(search_keyword, page)
    if not image_urls:
        print(f"共0个结果")
        os._exit(0)
    print(f"开始下载")
    download_images(image_urls)
